Skip to content

Conversation

@mrubens
Copy link
Collaborator

@mrubens mrubens commented Aug 26, 2025

Thanks to @thelicato for flagging this


Important

Enhance RooIgnoreController to resolve symlinks in validateAccess to prevent TOCTOU attacks, with corresponding tests added.

  • Behavior:
    • validateAccess in RooIgnoreController.ts now resolves symlinks to prevent TOCTOU attacks.
    • If realpathSync fails, falls back to the original path.
  • Tests:
    • Added test in RooIgnoreController.spec.ts to ensure symlinks pointing to ignored files are blocked.
    • Mocks fsSync.realpathSync to simulate symlink resolution.
  • Imports:
    • Added fsSync import in RooIgnoreController.ts for synchronous file operations.

This description was created by Ellipsis for ce9def7. You can customize this summary. It will automatically update as commits are pushed.

@mrubens mrubens requested review from cte and jr as code owners August 26, 2025 06:23
@dosubot dosubot bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Aug 26, 2025
Copy link
Contributor

@roomote roomote bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for addressing this important security issue! The implementation correctly resolves symlinks before checking ignore patterns, which effectively prevents TOCTOU attacks. I have left some suggestions for consideration below.

// Follow symlinks to get the real path
let realPath: string
try {
realPath = fsSync.realpathSync(absolutePath)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I notice we are using fsSync.realpathSync() which is a synchronous operation. Since validateAccess might be called frequently during file operations, have you considered the performance impact? Would it be worth exploring an async version or perhaps caching resolved paths to minimize the blocking I/O operations?

} catch {
// If realpath fails (file doesn't exist, broken symlink, etc.),
// use the original path
realPath = absolutePath
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When realpathSync fails, we silently fall back to the original path. While this maintains backward compatibility, it could mask issues like broken symlinks or permission problems. Would it be helpful to at least log these failures for debugging purposes?


/**
* Check if a file should be accessible to the LLM
* Automatically resolves symlinks
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment mentions Automatically resolves symlinks but does not explain why this is important. Would it help future maintainers to add a brief note about the security implications (TOCTOU prevention)?


// Ignore expects paths to be path.relative()'d
// Follow symlinks to get the real path
let realPath: string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider extracting this symlink resolution logic into a private helper method for better readability and potential reuse. This would make the main logic cleaner and the helper method could be reused if needed elsewhere.

expect(controller.validateAccess("node_modules/package.json")).toBe(false)

// Symlink to ignored file should also be blocked (TOCTOU fix)
expect(controller.validateAccess("config.json")).toBe(false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great test for the basic symlink scenario! Would it be valuable to add tests for edge cases like: broken symlinks (where realpathSync would throw), symlink chains (symlink pointing to another symlink), and circular symlinks?

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Aug 26, 2025
@daniel-lxs daniel-lxs moved this from Triage to PR [Needs Review] in Roo Code Roadmap Aug 26, 2025
Copy link
Member

@daniel-lxs daniel-lxs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Tested it and it works

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Aug 26, 2025
@hannesrudolph hannesrudolph added PR - Needs Review and removed Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. labels Aug 26, 2025
@mrubens mrubens merged commit a79c3d0 into main Aug 26, 2025
19 checks passed
@mrubens mrubens deleted the roo_ignore_resolve_symlinks branch August 26, 2025 14:12
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Aug 26, 2025
@github-project-automation github-project-automation bot moved this from PR [Needs Review] to Done in Roo Code Roadmap Aug 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer PR - Needs Review size:M This PR changes 30-99 lines, ignoring generated files.